#ifndef LBC_SUDOKU_220226_DEF
#define LBC_SUDOKU_220226_DEF

#include <stdint.h>
#include <vector>
#include <string>

typedef unsigned short BitsType;

#define KNOWN   1 // 是已知的
#define UNKNOWN 0 // 是未知的
#define FULLBITS 1022

#define SET_BIT(x,i) x|=(1<<i)
#define CLEAR_BIT(x,d)  x &= (~(1<<d))

#define BLOCK_NO(row,col) ((row)/3)*3+((col)/3)
#define IS_POWER2(x) ((x&(x-1))==0)

class Cell
{
public:
    // (candidate & (2^1))>0, the number can be 1
    // (candidate & (2^2))>0, the number can be 2
    // (candidate & (2^9))>0, the number can be 9
    BitsType candidate;

    // 0: the num is known:
    // 1: the num is unkonw, need resolve it
    uint8_t flag; 

    //0: is empty cell, 1-9, the num of this cell is num
    uint8_t num;
};

class candidateSequence
{
    struct StatusChange
    {
        BitsType mask;
        uint8_t byID;
    };

public:
    void init(BitsType m) 
    {
        sequences[0].byID=0;
        sequences[0].mask=m;
        activeIdx=0;
    }

    bool update(uint8_t source_id, int d )
    {
        while (sequences[activeIdx].byID >= source_id)
            activeIdx--;
        BitsType t=sequences[activeIdx].mask;
        CLEAR_BIT(t,d);
        if ( t==0 )
            return false;

        if ( t != sequences[activeIdx].mask )
        {
            activeIdx++;
            sequences[activeIdx].mask=t;
            sequences[activeIdx].byID=source_id;
        }
        return true;
    }

    BitsType get(uint8_t source_id)
    {
        while (activeIdx >= source_id)
            activeIdx--;
        return sequences[activeIdx].mask;
    }
private:
    struct StatusChange sequences[9];    // 状态改变序列
    uint8_t activeIdx;                  // 活动状态索引
};


class BlankCell
{
public:
    candidateSequence cs;
    uint16_t reltvAddr;   // first relatives address, 这个格子第一个亲属的地址
    uint8_t reltvCount;  // relatives count, 这个格子第一个亲属的个数
    uint8_t row;  // 行：有效的取值0到8
    uint8_t col;  // 列：有效的取值0到8
    uint8_t block; //宫：有效的取值0到8
};

// 定义一个回调函数类型
typedef void (*outputCallBack)(void *p,Cell cells[9][9]);

class Sudoku
{
public:
    void init(int a[]);
    void resolve(outputCallBack fun,void *pContent);
private:
    void preprocess();
    int  eliminateCandidateInRow(int row,int n); //从row行的所有空位的候选数字中删除n
    int  eliminateCandidateInCol(int col,int n);  //从col列的所有空位的候选数字中删除n
    int  eliminateCandidateInBlock(int block,int n); //从block宫中的所有空位的候选数中删除n
    void createAdvancedSearchContext();
    void tryFill(uint8_t currLayID,outputCallBack fun,void *pContent);   // 尝试填充ID大于等于firstLayID空白格子，这是一个递归函数

public:
    Cell cells[9][9];
private:
    std::vector<BlankCell> blankCells; // 这里，blankCells[0]是不使用的
    std::vector<uint8_t> reltvTable;   // relatives table 亲属表
};

int get_input(int ary[],int aryLen,FILE* fp );
void printStatus(void *p,Cell cells[9][9]);
void printResult(void *p,Cell cells[9][9]);

#endif